package org.xmx0632.connector.protocol.processor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xmx0632.connector.model.Gateway;
import org.xmx0632.connector.protocol.message.GatewayRegister0001UpRequest;
import org.xmx0632.connector.protocol.message.GatewayRegister0001UpResponse;
import org.xmx0632.connector.util.GlobalGateway;

/**
 * TODO 5.2 设备注册流程
 * 
 * 1. 根据设备ID检测内存中是否已经有存在连接信息。
 * 
 * 2. 如果有存在的连接信息，则断开原TCP连接。并更新内存里的连接信息。
 * 
 * 3. 如果没有存在的连接信息，则将连接信息保存至内存中。
 *
 */
@Component
public class GatewayRegister0001UpRequestProcessor
		extends BaseMessageProcessor<GatewayRegister0001UpRequest, GatewayRegister0001UpResponse> {

	public static final Logger LOG = LoggerFactory.getLogger(GatewayRegister0001UpRequestProcessor.class);

	@Override
	public GatewayRegister0001UpResponse process(GatewayRegister0001UpRequest message) {
		try {
			LOG.debug("process message:{}", message);

			if (message.getGateway() == null) {
				LOG.error("invalid request");
			}
			String gatewayId = message.getGateway().getGatewayId();
			LOG.debug("gatewayId:{}", gatewayId);

			String remoteAddress = message.getRemoteAddress();
			LOG.debug("remoteAddress:{}", remoteAddress);

			Gateway gateway = GlobalGateway.get(gatewayId);
			LOG.debug("gateway:{}", gateway);
			if (alreadyRegistered(gateway)) {
				// 如果有存在的连接信息，则断开原TCP连接.
				if (isDuplicateRegisterFromTheSameClient(remoteAddress, gateway)) {
					LOG.warn("duplicate register from the same client :{} with gatewayId:{}", remoteAddress, gatewayId);
				} else {
					LOG.debug("kickout old client:{} with gatewayId:{}", gateway.getChannel().remoteAddress(),
							gatewayId);
					// 踢掉前一个客户端
					gateway.getChannel().close();
				}
			}
			LOG.info("register client:{} gatewayId:{} success", remoteAddress, gatewayId);

			// 更新内存里的连接信息
			boolean registerSuccess = GlobalGateway.register(remoteAddress, gatewayId);
			if (registerSuccess) {
				return new GatewayRegister0001UpResponse(registerSuccess);
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}

		return new GatewayRegister0001UpResponse(false);
	}

	private boolean alreadyRegistered(Gateway gateway) {
		return gateway != null;
	}

	private boolean isDuplicateRegisterFromTheSameClient(String remoteAddress, Gateway gateway) {
		String oldClientAddress = gateway.getChannel().remoteAddress().toString();
		return oldClientAddress.equals(remoteAddress);
	}
}
